from abc import ABC, abstractmethod


class AbstractDecoder:
    """
    解析类的抽象类，定义了decode和is_valid两个抽象方法
    """

    def __init__(self, method):
        self.method = method

    @abstractmethod
    def decode(self, data, key):
        """
        :param data: 待解码的数据
        :param key: 解密密钥
        :param data: 待解码的数据
        :return: 解码后的字符串
        """
        pass

    @abstractmethod
    def is_valid(self, data, key):
        """
        :param data: 待验证的数据
        :param key: 解密密钥
        :param data: 待验证的数据
        :return: True if valid, False otherwise
        """
        pass

    def reset(self):
        pass


class DecoderGroup:
    """
    解析器集合类，用于管理多个解析器
    """

    _instance = None

    def __new__(cls, *args, **kwargs):
        """
        单例模式
        :return: 实例对象
        """
        if not cls._instance:
            cls._instance = super().__new__(cls)
        return cls._instance

    def __init__(self):
        self.decoders = []
        self.deep = 0

    def add_decoder(self, decoder):
        """
        添加解析器
        :param decoder: 解析器实例
        """
        self.decoders.append(decoder)

    def decode(self, data, key):
        """
        解码方法，根据data参数选择对应的解析器进行解码,直至无法解析为止，最大探寻深度为10
        :param data: 待解码的数据
        :return: 解码后的字符串
        """
        result = data
        for decoder in self.decoders:
            if decoder.is_valid(data, key) and self.deep < 10:                
                print(f"正在使用{decoder.method}解码...")
                result = decoder.decode(data, key)
                decoder.reset()
                print(f"解码结果：{result}")
                self.deep += 1
                print(f"深度尝试：{self.deep} 次")                
                result = self.decode(result, key)

        return result

    def decode_file(self, file_path: str, key=None):
        """
        解码文件方法，根据文件路径读取文件内容并进行解码
        :param file_path: 文件路径
        :return: 解码后的字符串
        """
        with open(file_path, "r") as file:
            data = file.read()
        return self.decode(data, key)
